package org.jsola.hr.service.impl;

import cn.hutool.core.lang.Validator;
import com.alibaba.excel.EasyExcel;
import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.ICrmCustomerImportRecordDAO;
import org.jsola.hr.dto.*;
import org.jsola.hr.dto.excel.CrmCustomerImportDTO;
import org.jsola.hr.entity.CrmCustomerImportRecordDO;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.query.CrmCustomerImportDetailsQuery;
import org.jsola.hr.query.CrmCustomerImportRecordQuery;
import org.jsola.hr.query.CrmCustomerInfoQuery;
import org.jsola.hr.query.CrmMemberQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.service.excel.CrmCustomerImportListener;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 导入客户记录表
 *
 * @author zhr
 */
@Service("hrCrmCustomerImportRecordServiceImpl")
public class CrmCustomerImportRecordServiceImpl implements ICrmCustomerImportRecordService {

    @Autowired
    private ICrmCustomerImportRecordDAO crmCustomerImportRecordDAO;

    @Autowired
    private ICrmCustomerImportDetailsService crmCustomerImportDetailsService;

    @Autowired
    private ICrmCustomerInfoService crmCustomerInfoService;

    @Autowired
    private ICrmMemberService crmMemberService;

    @Autowired
    private ICrmCustomerDistributionRecordService crmCustomerDistributionRecordService;

    @Override
    public InputStream getErrorCustomerData(String recordId, TokenUser tokenUser) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        //错误数据
        CrmCustomerImportDetailsQuery crmCustomerImportDetailsQuery = new CrmCustomerImportDetailsQuery();
        crmCustomerImportDetailsQuery.setIsError(true);
        crmCustomerImportDetailsQuery.setRecordId(recordId);
        List<CrmCustomerImportDetailsListVO> crmCustomerImportDetailsListVOList = crmCustomerImportDetailsService.select(crmCustomerImportDetailsQuery, tokenUser.getSiteId());

        //数据
        List<List<String>> dataList = new ArrayList<>();
        for (CrmCustomerImportDetailsListVO crmCustomerImportDetailsListVO : crmCustomerImportDetailsListVOList) {
            ArrayList<String> strings = new ArrayList<>();
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getErrorReason())?crmCustomerImportDetailsListVO.getErrorReason():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getName())?crmCustomerImportDetailsListVO.getName():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getPhone())?crmCustomerImportDetailsListVO.getPhone():null);
            strings.add(crmCustomerImportDetailsListVO.getGender() != null?
                    (crmCustomerImportDetailsListVO.getGender()==1?
                            "男":(crmCustomerImportDetailsListVO.getGender()==2 ?
                            "女":"未知")):null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getEmail())?crmCustomerImportDetailsListVO.getEmail():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getWechat())?crmCustomerImportDetailsListVO.getWechat():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getPostName())?crmCustomerImportDetailsListVO.getPostName():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getCompanyName())?crmCustomerImportDetailsListVO.getCompanyName():null);
            strings.add(!StringUtils.isEmpty(crmCustomerImportDetailsListVO.getCompanyAddress())?crmCustomerImportDetailsListVO.getCompanyAddress():null);
            if(crmCustomerImportDetailsListVO.getCompanyType()!= null){
                if(crmCustomerImportDetailsListVO.getCompanyType() == 1){
                    strings.add("有限责任");
                }else if(crmCustomerImportDetailsListVO.getCompanyType() == 2){
                    strings.add("个人独资");
                }else if(crmCustomerImportDetailsListVO.getCompanyType() == 3){
                    strings.add("股权有限责任");
                }else if(crmCustomerImportDetailsListVO.getCompanyType() == 4){
                    strings.add("其他");
                }
            }else {
                strings.add(null);
            }
            if(crmCustomerImportDetailsListVO.getCompanyPersonSize()!= null){
                if(crmCustomerImportDetailsListVO.getCompanyPersonSize() == 1){
                    strings.add("500以下");
                }else if(crmCustomerImportDetailsListVO.getCompanyPersonSize() == 2){
                    strings.add("500-1000");
                }else if(crmCustomerImportDetailsListVO.getCompanyPersonSize() == 3){
                    strings.add("1000-3000");
                }else if(crmCustomerImportDetailsListVO.getCompanyPersonSize() == 4){
                    strings.add("3000以上");
                }
            }else {
                strings.add(null);
            }
            dataList.add(strings);
        }
        //制作表头
        List<List<String>> list = new ArrayList<>();
        for (int i = 0; i < 11; i++) {
            ArrayList<String> list1 = new ArrayList<>();
            if(i==0){
                list1.add("错误信息");
            }else if(i == 1){
                list1.add("姓名");
            }else if(i == 2){
                list1.add("手机");
            }else if(i == 3){
                list1.add("性别");
            }else if(i == 4){
                list1.add("邮箱");
            }else if(i == 5){
                list1.add("微信");
            }else if(i == 6){
                list1.add("职位");
            }else if(i == 7){
                list1.add("公司名称");
            }else if(i == 8){
                list1.add("公司地址");
            }else if(i == 9){
                list1.add("公司类型");
            }else if(i == 10){
                list1.add("公司规模");
            }
            list.add(list1);
        }
        EasyExcel.write(outputStream)
                .head(list)
                .sheet("客户导入错误数据")
                .doWrite(dataList);
        return new ByteArrayInputStream(outputStream.toByteArray());
    }

    @Override
    public Integer importCustomerInfo(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, TokenUser tokenUser) {
        CrmMemberQuery crmMemberQuery = new CrmMemberQuery();
        crmMemberQuery.setUserId(tokenUser.getUserId());
        List<CrmMemberListVO> select1 = crmMemberService.select(crmMemberQuery, tokenUser.getSiteId());
        CrmCustomerImportDetailsQuery crmCustomerImportDetailsQuery = new CrmCustomerImportDetailsQuery();
        crmCustomerImportDetailsQuery.setIsError(false);
        crmCustomerImportDetailsQuery.setRecordId(crmCustomerImportRecordQuery.getRecordId());
        List<CrmCustomerImportDetailsListVO> select = crmCustomerImportDetailsService.select(crmCustomerImportDetailsQuery,tokenUser.getSiteId());
        for (CrmCustomerImportDetailsListVO crmCustomerImportDetailsListVO : select) {
            CrmCustomerInfoAddDTO crmCustomerInfoAddDTO = crmCustomerImportDetailsListVO.to(CrmCustomerInfoAddDTO.class);
            if(!crmCustomerImportRecordQuery.getIsPublic()){
                crmCustomerInfoAddDTO.setIsPublic(false);
                crmCustomerInfoAddDTO.setUserId(tokenUser.getUserId());
                crmCustomerInfoAddDTO.setMemberId(select1.get(0).getId());
                crmCustomerInfoAddDTO.setMemberName(select1.get(0).getName());
            }else {
                crmCustomerInfoAddDTO.setIsPublic(true);
            }
            crmCustomerInfoAddDTO.setDistributeName(tokenUser.getUserName());
            crmCustomerInfoAddDTO.setSourceUserId(tokenUser.getUserId());
            crmCustomerInfoAddDTO.setType(1);
            crmCustomerInfoAddDTO.setSourceType(2);
            crmCustomerInfoAddDTO.setIsSign(false);
            crmCustomerInfoAddDTO.setSourceName(tokenUser.getUserName());
            CrmCustomerInfoVO crmCustomerInfoVO = crmCustomerInfoService.save(crmCustomerInfoAddDTO, tokenUser);
            //分配记录
            CrmCustomerDistributionRecordAddDTO crmCustomerDistributionRecordAddDTO = new CrmCustomerDistributionRecordAddDTO();
            crmCustomerDistributionRecordAddDTO.setCustomerId(crmCustomerInfoVO.getId());
            crmCustomerDistributionRecordAddDTO.setDistributionInfo("由"+tokenUser.getUserName()+"导入");
            crmCustomerDistributionRecordService.save(crmCustomerDistributionRecordAddDTO,tokenUser);
        }
        return select.size();
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public CrmCustomerImportRecordVO importFile(MultipartFile file, TokenUser tokenUser) {
        //保存记录
        CrmCustomerImportRecordAddDTO crmCustomerImportRecordAddDTO = new CrmCustomerImportRecordAddDTO();
        crmCustomerImportRecordAddDTO.setDataType("客户导入记录");
        crmCustomerImportRecordAddDTO.setFileName(file.getOriginalFilename());
        CrmCustomerImportRecordVO crmCustomerImportRecordVO = save(crmCustomerImportRecordAddDTO, tokenUser);
        CrmCustomerImportListener crmCustomerImportListener = new CrmCustomerImportListener();
        try {
            EasyExcel.read(file.getInputStream(),crmCustomerImportListener).sheet().doRead();
        } catch (Exception e) {
            throw new HrException("文件上传失败");
        }
        List<CrmCustomerImportDTO> crmCustomerImportDTOList = crmCustomerImportListener.getList();
        for (CrmCustomerImportDTO crmCustomerImportDTO : crmCustomerImportDTOList) {
            CrmCustomerImportDetailsAddDTO crmCustomerImportDetailsAddDTO = crmCustomerImportDTO.to(CrmCustomerImportDetailsAddDTO.class);
            crmCustomerImportDetailsAddDTO.setIsError(false);
            //格式校验
            if(StringUtils.isEmpty(crmCustomerImportDTO.getPhone())){
                crmCustomerImportDetailsAddDTO.setErrorReason("手机号为空");
            }else {
                if(!Validator.isMobile(crmCustomerImportDTO.getPhone())){
                    crmCustomerImportDetailsAddDTO.setErrorReason("手机号格式错误");
                }
            }

            if (StringUtils.isEmpty(crmCustomerImportDTO.getName())){
                crmCustomerImportDetailsAddDTO.setErrorReason("姓名为空");
            }else if((crmCustomerImportDTO.getName().length()>20)){
                crmCustomerImportDetailsAddDTO.setErrorReason("姓名格式错误");
            }
            if(StringUtils.isEmpty(crmCustomerImportDTO.getCompanyName())){
                crmCustomerImportDetailsAddDTO.setErrorReason("公司名称为空");
            }
            crmCustomerImportDetailsAddDTO.setName(crmCustomerImportDTO.getName());
            if(!StringUtils.isEmpty(crmCustomerImportDTO.getEmail()) && !Validator.isEmail(crmCustomerImportDTO.getEmail())){
                crmCustomerImportDetailsAddDTO.setErrorReason("邮箱格式错误");
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getWechat()) && crmCustomerImportDTO.getWechat().length()>20){
                crmCustomerImportDetailsAddDTO.setErrorReason("微信格式错误");
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getPostName()) && crmCustomerImportDTO.getPostName().length()>100){
                crmCustomerImportDetailsAddDTO.setErrorReason("职位格式错误");
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getCompanyName()) && crmCustomerImportDTO.getCompanyName().length()>50){
                crmCustomerImportDetailsAddDTO.setErrorReason("公司名称格式错误");
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getCompanyAddress()) && crmCustomerImportDTO.getCompanyAddress().length()>50){
                crmCustomerImportDetailsAddDTO.setErrorReason("公司地址格式错误");
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getCompanyType())){
                if(!(crmCustomerImportDTO.getCompanyType()>0 && crmCustomerImportDTO.getCompanyType()<5)){
                    crmCustomerImportDetailsAddDTO.setErrorReason("公司类型格式错误");
                }
            }else if(!StringUtils.isEmpty(crmCustomerImportDTO.getCompanyPersonSize())){
                if(!(crmCustomerImportDTO.getCompanyPersonSize() > 0 && crmCustomerImportDTO.getCompanyPersonSize()< 5)){
                    crmCustomerImportDetailsAddDTO.setErrorReason("公司规模格式错误");
                }
            }
            if(!StringUtils.isEmpty(crmCustomerImportDTO.getCompanyName())){
                //导入表公司重复校验
                CrmCustomerImportDetailsQuery crmCustomerImportDetailsQuery = new CrmCustomerImportDetailsQuery();
                crmCustomerImportDetailsQuery.setCompanyName(crmCustomerImportDTO.getCompanyName());
                crmCustomerImportDetailsQuery.setRecordId(crmCustomerImportRecordVO.getId());
                List<CrmCustomerImportDetailsListVO> select = crmCustomerImportDetailsService.select(crmCustomerImportDetailsQuery, tokenUser.getSiteId());
                if(!CollectionUtils.isEmpty(select)){
                    CrmCustomerImportDetailsUpdateDTO crmCustomerImportDetailsUpdateDTO = new CrmCustomerImportDetailsUpdateDTO();
                    crmCustomerImportDetailsUpdateDTO.setId(select.get(0).getId());
                    crmCustomerImportDetailsUpdateDTO.setIsError(true);
                    crmCustomerImportDetailsUpdateDTO.setErrorReason("公司名称重复");
                    crmCustomerImportDetailsService.update(crmCustomerImportDetailsUpdateDTO,tokenUser);
                    crmCustomerImportDetailsAddDTO.setErrorReason("公司名称重复");
                }
                //客户表公司重复校验
                CrmCustomerInfoQuery crmCustomerInfoQuery = new CrmCustomerInfoQuery();
                crmCustomerInfoQuery.setCompanyName(crmCustomerImportDTO.getCompanyName());
                List<CrmCustomerInfoListVO> select1 = crmCustomerInfoService.select(crmCustomerInfoQuery, tokenUser.getSiteId());
                if(!CollectionUtils.isEmpty(select1)){
                    crmCustomerImportDetailsAddDTO.setErrorReason("已录入该公司名称");
                }
            }

            if(!StringUtils.isEmpty(crmCustomerImportDetailsAddDTO.getErrorReason())){
                crmCustomerImportDetailsAddDTO.setIsError(true);
            }
            crmCustomerImportDetailsAddDTO.setRecordId(crmCustomerImportRecordVO.getId());
            crmCustomerImportDetailsService.save(crmCustomerImportDetailsAddDTO,tokenUser);
        }
        //查询错误数据
        CrmCustomerImportDetailsQuery crmCustomerImportDetailsQuery = new CrmCustomerImportDetailsQuery();
        crmCustomerImportDetailsQuery.setIsError(true);
        crmCustomerImportDetailsQuery.setRecordId(crmCustomerImportRecordVO.getId());
        int count = crmCustomerImportDetailsService.selectCount(crmCustomerImportDetailsQuery, tokenUser.getSiteId());
        String errorMessage = "导入客户名单"+file.getOriginalFilename()+"共"+crmCustomerImportDTOList.size()+"人,有"+count+"条数据异常，请尽快处理";
        if(count == 0){
            errorMessage = "导入客户名单"+file.getOriginalFilename()+"共"+crmCustomerImportDTOList.size()+"人，无异常数据";
        }
        crmCustomerImportRecordVO.setErrorMessage(errorMessage);
        return crmCustomerImportRecordVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public CrmCustomerImportRecordVO save(CrmCustomerImportRecordAddDTO crmCustomerImportRecordAddDTO, TokenUser tokenUser) {
        // 转DO
        CrmCustomerImportRecordDO crmCustomerImportRecordDO = crmCustomerImportRecordAddDTO.to(CrmCustomerImportRecordDO.class);
        // 保存
        crmCustomerImportRecordDO = save(crmCustomerImportRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return crmCustomerImportRecordDO.to(CrmCustomerImportRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(CrmCustomerImportRecordUpdateDTO crmCustomerImportRecordUpdateDTO, TokenUser tokenUser) {
        //转DO
        CrmCustomerImportRecordDO crmCustomerImportRecordDO = crmCustomerImportRecordUpdateDTO.to(CrmCustomerImportRecordDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(crmCustomerImportRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... crmCustomerImportRecordIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) crmCustomerImportRecordIds);
    }


    @Override
    public CrmCustomerImportRecordVO selectById(String crmCustomerImportRecordId, String siteId) {
        CrmCustomerImportRecordDO crmCustomerImportRecordDO = selectDOById(crmCustomerImportRecordId, siteId);
        if (crmCustomerImportRecordDO == null) {
            return null;
        }
        return crmCustomerImportRecordDO.to(CrmCustomerImportRecordVO.class);
    }

    @Override
    public List<CrmCustomerImportRecordListVO> select(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, String siteId) {
        List<CrmCustomerImportRecordDO> crmCustomerImportRecordDOList = selectDO(crmCustomerImportRecordQuery, siteId);
        if(CollectionUtils.isEmpty(crmCustomerImportRecordDOList)) {
            return crmCustomerImportRecordDOList == null ? null : new ArrayList<>();
        }
        return crmCustomerImportRecordDOList.stream()
                .map(crmCustomerImportRecordDO -> crmCustomerImportRecordDO.to(CrmCustomerImportRecordListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, String siteId) {
        Example example = buildExample(crmCustomerImportRecordQuery,siteId);
        return crmCustomerImportRecordDAO.selectCountByExample(example);
    }

    @Override
    public Page<CrmCustomerImportRecordListVO> selectPage(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, String siteId) {
        Example example = buildExample(crmCustomerImportRecordQuery,siteId);
        Page<CrmCustomerImportRecordDO> page = crmCustomerImportRecordDAO.selectPageByExample(example,
                crmCustomerImportRecordQuery.getPageNo(),
                crmCustomerImportRecordQuery.getPageSize());

        return page.to(CrmCustomerImportRecordListVO.class);
    }

    @Override
    public CrmCustomerImportRecordDO selectDOById(String crmCustomerImportRecordId, String siteId) {
        return listById(crmCustomerImportRecordId, siteId);
    }

    @Override
    public List<CrmCustomerImportRecordDO> selectDO(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, String siteId) {
        Example example = buildExample(crmCustomerImportRecordQuery,siteId);
        return crmCustomerImportRecordDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example

     * @param crmCustomerImportRecordQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(CrmCustomerImportRecordQuery crmCustomerImportRecordQuery, String siteId) {
        Example example = new Example(CrmCustomerImportRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        ExampleKit.setExampleOrder(example,crmCustomerImportRecordQuery.getOrders());
        return example;
    }
}




